<?php

/**
 * @author liyi
 * @copyright 2019年1月17日 14:35:37
 */

namespace Sdgame\Controller;
use Common\Controller\ApiController;

class IndexController extends ApiController {
    
    const GAME_TYPE = 'Sdgame';  // 游戏类型

    const USER_UID = "sdgame:user:%s:qid:%s";  // 用户主键分享到群

    const USER_INVITE = "sdgame:user:%s:invite"; // 用户邀请记录键

    const SDGAME_TOURIST = "sdgames:tourist:sid:%s"; // 游戏游客用户

    const SDGAME_AUTH_USER = "sdgames:auth_user:sid:%s";  // 授权用户

    const SDGAME_PLAY = "sdgames:play"; // 游戏次数

    const SDGAME_SHARE = "sdgames:share";  // 普通分享次数

    const SDGAME_INVITE = "sdgames:invite"; // 邀请次数

    const RANK_LIST = "sdgame:rankList"; // 排汗榜列表(缓存)

    const SDGAME_KEY = "sdgames"; // session_key 判断

    const SDGAME_SID_KEY = "sdgames:%s:sid:%s"; // 渠道来源缓存键

    const SDGAME_COUNT_KEY = "sdgames:count"; // 渠道来源统计缓存键

    public function __construct()
    {
        parent::__construct();

        $source = I('source',0,'int');  // 渠道来源
        $z_index = I('z_index',0,'int'); // 用户层级
        $sidIndex = $source.'-'.$z_index; // 渠道用户来源层级
        $this->sid = $source;
        $this->sidIndex = $sidIndex;
    }

    // 未授权登陆
    public function loginNotAuth()
    {
        $id = I('id','','string');
        $code = I('code','','string');
        $sid = $this->sid;
        $sidIndex = $this->sidIndex;

        if(!$code) {
            $this->response(1,'code不能为空');
        }
        $gameType = self::GAME_TYPE;
        $info = $this->wxAuthor($gameType,$code);

        $data['openid'] = $info['openid'];


        $content['openid'] = $info['openid'] ? $info['openid'] : $id;

        $users = M('users')->where($content)->find();
        
        if(empty($users)) {
            $data['create_time'] = date('Y-m-d H:i:s');
            $data['types'] = 1;//新用户
            $ret = M('users')->add($data);
            if(empty($ret)) {
                $this->response(1,'操作失败');
            }

            $map['id'] = $ret;
            $userInfo = M('users')->where($map)->find();
            $userInfo['session_key'] = $info['session_key'];

            $sdgameTourist = sprintf(self::SDGAME_TOURIST,$sidIndex);
            $incr = $this->countLog(self::SDGAME_KEY,$sdgameTourist);  // 记录游客用户(相当于总用户)
            $this->getChannelCount(self::SDGAME_COUNT_KEY,$sidIndex,'tourist',$incr);

            $this->response(0,'ok',$userInfo);
        }else{
            if($data['types'] != 4){
                if($users['status']!=2){
                    //未授权第二次登录
                    $data['types'] = 2;
                }else{
                    // 授权登录
                    if(!empty($users['nickname']) && !empty($users['avatar'])){
                        $data['types'] = 4;
                    }else{
                        $data['types'] = 3;
                    }

                }
                $data['update_time'] = date('Y-m-d H:i:s');

                $ret = M('users')->where($content)->save($data);
                if(empty($ret)) {
                    $this->response(1,'操作失败');
                }
            }

            $userInfo = M('users')->where($content)->find();
            $userInfo['session_key'] = $info['session_key'];
            $this->response(0,'ok',$userInfo);

        }

    } 
    
    // 登陆接口
    public function login()
    {
        $nickname = I('nickname','','string');
        $avatar = I('avatar','','string');
        $id = I('id','0','int');
        $openid = I('openid','','string');
        $sid = $this->sid;
        $sidIndex = $this->sidIndex;

        $map['openid'] = $openid;
            
        $users = M('users')->where($map)->find();
        if(empty($users)){
            $dateline = date('Y-m-d H:i:s');
            $param = array(
                'openid'=>$openid,
                'nickname'=>$nickname,
                'avatar'=>$avatar,
                'create_time'=>$dateline,
                'status'=>2,
                'types'=>3
            );
            $ret = M('users')->add($param);
        }else {
            $data = array('nickname'=>$nickname,'avatar'=>$avatar,'status'=>2);
            if($users['status'] != 2) {  // 未授权取值
                $data['update_time'] = date("Y-m-d H:i:s");
                if(!empty($users['nickname']) && !empty($users['avatar'])){
                    $data['types'] = 4;  //第二次
                }else{
                    $data['types'] = 3;  //第一次
                }
                $sdgameTourist = sprintf(self::SDGAME_AUTH_USER,$sidIndex);
                $incr = $this->countLog(self::SDGAME_KEY,$sdgameTourist);  // 授权用户可能重复
                $this->getChannelCount(self::SDGAME_COUNT_KEY,$sidIndex,'auth_user',$incr);
            }
            M('users')->where($map)->save($data);
        }
 
        // 返回用户最优成绩
        $userInfo = M('users')->where($map)->find();
        $this->response(0,'ok',$userInfo);
    }

    // 记录用户点击分享按钮的次数
    public function setShare() {
        $id = I('id','','string'); // 用户userid
        $type = I('type',1,'int');  // 1:分享次数 2：分享完成(暂停) 3：看完视频次数 4：点击视频次数
        $sid = $this->sid;  // 渠道来源
        $sidIndex = $this->sidIndex;
           
        if(!in_array($type,array(1,3,4))) {
            $this->response(1,'非法的分享类型');
        }

        $arr = array(1=>'share',3=>'video_close',4=>'video_click');
        $typeName = $arr[$type];

        $userKey = self::SDGAME_KEY;
        $userVal = sprintf(self::SDGAME_SID_KEY,$typeName,$sidIndex);  //用户主键分享到群
        $countKey = self::SDGAME_COUNT_KEY;

        $incr = $this->countLog($userKey,$userVal);  // 记录看完视频的次数

        $this->getChannelCount($countKey,$sidIndex,$typeName,$incr);

        $this->response(0,'ok');
    }

    // 解密数据
    public function cryptData()
    {
        $appid = C('APPID'); // Appid
        $sessionKey = I('sessionKey','','string'); // sessionKey
        $encryptedData = I('encryptedData','','string'); // 加密数据
        $iv = I('iv','','string');
        $id = I('id','','int'); // 用户id
        $type = I('type',1,'int');

        $pc = new \Org\Util\WXBizDataCrypt($appid, $sessionKey);
        $errCode = $pc->decryptData($encryptedData, $iv, $data);
   
        $data = $data ? json_decode($data, true) : '';
        $openGId = isset($data['openGId']) ? $data['openGId'] : 0;
        $redis = REDIS('activity');
        $userKey = sprintf(self::USER_UID,$id,$openGId);  //用户主键分享到群
        $shareKey = $redis->get($userKey);
        if( $shareKey > 0 ) {
            $this->response(2,'每日同一群只能分享一次');
        }
        
        if ( $errCode == 0 ) {  // 解密成功
         
            $evening = date('Y-m-d 23:59:59'); //每日23点59分
            $redis->set($userKey,1);  // 标记
            $redis->exprieAt($userKey,strtotime($evening)); // 每日23点59分过期
            $result = $data ? json_decode($data, true) : '';
            //$this->countLog(self::SDGAME_KEY,self::SDGAME_SHARE);  // 玩游戏分享次数
            $this->response(0, "成功解密",$result);
        }
       
        $this->response(1, "解密失败");
    }
    
    // 排行榜
    public function rankingList()
    {
        $uid = I('id','','string');
        if ( !$uid ){
            $this->response(1,'请先登录');
        }

        $redis = REDIS('activity');
        $redis->select(2);
        $hash_key = self::RANK_LIST;    //排行榜缓存键

        $ret = $this->getRankList($hash_key,true,2,'score');
        if(empty($ret)) {
            $where['black_list'] = 1;
            $where['status'] = 2;
            $ret = M('users')->field('id,nickname,avatar,good_score as score')->where($where)->order('score desc')->limit(200)->select();
            foreach($ret as $k=>$v) {
                if(!empty($v['nickname']) && !empty($v['avatar'])){
                    $id = $v['id'];
                    $flag = $redis->hSet($hash_key,$id, json_encode($v));
                }
            }
        }

        $this->response(0,"ok",$ret);
    }

    // 积分排行榜
    public function gradeList()
    {
        $uid = I('id','','string');
        if ( !$uid ){
            $this->response(1,'请先登录');
        }

        $ret = array();
        $model = M('users');
        $field = "id,nickname,avatar,grade";
        $map['status'] = 2;
        $map['grade'] = array('neq',0);

        $ret = $model->field($field)->where($map)->order('grade desc')->limit(200)->select();
        $this->response(0,"ok",$ret);
    }

    // 设置金币
    public function setGolds()
    {
        $uid = I('id','0','int');
        $gold = I('gold','0','int');
        $data['gold'] = $gold;
        $map['id'] = $uid;
        $ret = M('users')->where($map)->save($data);
   
        $this->response(0,"操作成功");
    }

    // 记录游戏结束次数
    public function recordPlay() {
        $sid = $this->sid;
        $sidIndex = $this->sidIndex;
        $incr = $this->countLog(self::SDGAME_KEY,self::SDGAME_PLAY.':sid:'.$sidIndex);  // 玩游戏次数
        $this->getChannelCount(self::SDGAME_COUNT_KEY,$sidIndex,'play',$incr);
        $this->response(0,"操作成功");
    }
    
    // 获取用户邀请列表
    public function getUserInvite()
    {
        $uid = I('id',0,'int');
        $type = I('type',1,'int'); //1:每日邀请
        $map['invite_uid'] = $uid;
        $map['type'] = $type;
        $map['create_time'] = date('Y-m-d');
        $list = M('users_invite')->field('uid')->where($map)->order('id asc')->limit(6)->select();

        $userInfo = array();
        $number = 0;
        if(!empty($list)) {
            $number = intval(count($list));
            $uidArr = array_column($list,'uid');
            $uidStr = implode(',', $uidArr);
            $where['id'] = array('in',$uidStr);
            $userInfo = M('users')->field('id,nickname,avatar')->where($where)->select();
            if(!empty($userInfo)) {
                // 获取当天的邀请记录
                $redis = REDIS('activity');
                $inviteKey = sprintf(self::USER_INVITE,$uid);
                $invite = $redis->get($inviteKey);
                $invites = !empty($invite) ? json_decode($invite,true) : array();

                foreach($userInfo as $k=>$v) {
                    $userInfo[$k]['status'] = in_array($v['id'], $invites) ? 2 : 1;  // 1:未领取 2：已领取       
                }
            }
        }
        
        $this->response(0,"ok",array('userInfo'=>$userInfo,'number'=>$number));
    }

    // 领取邀请记录
    public function getReward() {
        $uid = I('id',0,'int');
        $inviteUidStr = I('inviteUidStr',0,'string');
        if(empty($inviteUidStr)) {
            $this->response(1,'邀请用户不能为空');
        }

        $inviteUidArr = explode(',',$inviteUidStr);
        
        $redis = REDIS('activity');
        $inviteKey = sprintf(self::USER_INVITE,$uid);  // 记录分享记录
        $redis->set($inviteKey,json_encode($inviteUidArr));
        $redis->exprieAt($inviteKey,strtotime(date('Y-m-d 23:59:59'))); // 每日23点59分过期

        $this->response(0,"操作成功");
    }
    
    /**
     * 邀请记录
     * @param  int $uid  邀请人编号
     * @param  int $invite_uid 被邀请人编号
     * @return array
     */
    public function inviteRecord()
    {
        $uid = I('id',0,'int');
        $invite_uid = I('invite_uid',0,'int');
        $sid = $this->sid;
        $sidIndex = $this->sidIndex;
        
        if(empty($uid) || empty($invite_uid)) {
            $this->response(4, "邀请人与被邀请人不能为空");
        }
        $type = I('type',1,'int');  // 1:任务邀请 
        $time = date('Y-m-d');

        if(empty($invite_uid)) {
            $this->response(2, "邀请人id不能为空");
        }

        $map['uid'] = $uid;
        $map['create_time'] = $time;
        $user = M('users_invite')->where($map)->find();
        
        if (!empty($user))
        {
            $this->response(3, "已被邀请过");
        }

        if( $uid != $invite_uid ) {  //如果不是自己邀请自己
            // 转发邀请记录
            $typeForward = array("101", "102", "103");
            if (in_array($type, $typeForward)) {
                $type_table = 'sd';   // redis表
                $this->getForward($uid, $invite_uid, $type_table, $type);
            }

            $data['uid'] = $uid;
            $data['invite_uid'] = $invite_uid;
            $data['create_time'] = $time;
            $data['type'] = $type;
            $ret = M('users_invite')->add($data);
            if(empty($ret)) {
                $this->response(1, "操作失败");
            } 
            $incr = $this->countLog(self::SDGAME_KEY,self::SDGAME_INVITE.':sid:'.$sidIndex);  // 邀请用户次数
            $this->getChannelCount(self::SDGAME_COUNT_KEY,$sidIndex,'invite',$incr);
        }
        $this->response(0, "操作成功");
    }


    // 获取session_key
    public function getSessionKey() {
        $gameType = self::GAME_TYPE;
        $code = I('code','','string');
        if(!$code) {
            $this->response(2,'code不能为空');
        }
        $info = $this->wxAuthor($gameType,$code);
        if(empty($info)) {
            $this->response(1,"操作失败"); 
        }

        $this->response(0, "ok",array('session_key'=>$info['session_key']));
    }

    // 游戏结束记录
    public function addGameResult() {

        $uid = I('id',0,'int');
        $good_score = I('score',0,'string');
        $grade = I('grade',-1,'string');
        $gold = I('gold',-1,'string');
        $type = I('type',1,'int');  // 1: 正常模式 2：积分模式
        $lv = I('lv',1,'int'); // 默认是菜鸟

        $map['id'] = $uid;
        $userInfo = M('users')->where($map)->find();

        $redis = REDIS('activity');
        $redis->select(2);
        $hashKey = self::RANK_LIST; //排行榜列表
        $rank_list = $redis->hGetAll($hashKey);
        if($rank_list){
            $data = array('id'=>$userInfo['id'],'score'=>$good_score,'userid'=>$userInfo['userid'],'nickname'=>$userInfo['nickname'],'avatar'=>$userInfo['avatar']);
            $this->setRankList($hashKey,2,$data,$userInfo['id'],'score',$good_score);// 记录缓存成绩
        }

        if($type == 1) {  // 正常模式
            if(empty($good_score)) {
                $this->response('2','成绩不能为空');
            }

            if($good_score > $userInfo['good_score']) {
                $data['good_score'] = $good_score;
                if($gold != '-1') {
                    $data['gold'] = $gold;
                }
                $data['best_rank'] = $this->getBestRank($uid,$good_score);
                M('users')->where($map)->save($data);
            }
        }

        if($type == 2 ) {  // 积分模式
            if(empty($grade)) {
                $this->response('3','积分不能为空');
            }
           
            $data['grade'] = $grade;
            $data['lv'] = $lv;
            if($gold != '-1') {
                $data['gold'] = $gold;
            }
            $dbname = 'sdxxl_game.users';
            $field = 'id,nickname,avatar,grade';
            $data['best_grade'] = $this->commBestRank($uid,$dbname,$grade,$field,'grade','grade desc');
            M('users')->where($map)->save($data);
        
        }
            
        $this->response(0,'操作成功');
    }

    // 匹配系统用户
    public function getMatchUser() {
        $uid = I('id',0,'int');
        $grade = I('grade',0,'int');
        $limit = 20;

        $start_grade = $grade < 1000 ? $grade : $grade - 1000;
        $end_grade =  $grade + 1000;
        
        $field = 'id,nickname,avatar,good_score,grade';

        $where['status'] = 2;
        $userList = M('users')->field($field)->where("grade > $start_grade AND grade <= $end_grade AND grade != 0 AND status = 2")->limit($limit)->select();

        $total = $limit - count($userList);
        $lastList = array();
        if($total > 0 ) {
            $where['grade'] = array('elt',$start_grade);
            $lastList = M('users')->field($field)->where($where)->order('grade desc')->limit($total)->select();         
        }

        $info = !empty($lastList) ? array_merge($userList,$lastList) : $userList;
        
        // 过滤掉自己
        foreach($info as $k=>$v) {
            if($uid == $v['id'] ) {
                unset($info[$k]);
            }
        }

        shuffle($info);  // 打乱数组排序
        $this->response(0,'ok',$info);       
    }

    // 获取对战用户数据
    public function getFightList() {
        $fightId = I('fightid','','string');
        if(!empty($fightId)) {
            $this->response(1,'对战好友为空');
        }
        $map['id'] = $fightId;
        $ret = M('users')->field('id,nickname,avatar,grade')->where($map)->find();
        $this->response(0,'ok',$ret);
    }

    /**
     * 最佳成绩排名
     * @param  int $uid 用户id
     * @param  int $good_score 最佳成绩
     * @return int
     */
    public function getBestRank($uid,$good_score) {

        $where['status'] = 2;  // 授权用户
        // $where['good_score'] = array('neq',0,'AND');
        // $where['nickname']  = array('not in',array('undefined',''));
        // $where['avatar']  = array('not in', array('undefined',''));

        $ret = M('users')->field('id,nickname,avatar,good_score AS score')->where($where)->order('score desc,id asc')->limit(200)->select();

        $rankNum = 0; // 排名
        if(!empty($ret)) {

            foreach($ret as $k=>$v) {
               
                if( $uid == $v['id'] && $good_score >= $v['score'] ) {                
                    $rankNum = $k + 1;
                    break;
                }
                
                if( $good_score > $v['score'] ) {
                    $rankNum = $k + 1;
                    break;
                }     
            }   
        }

        if( $rankNum == 0 ) {

            $rankNum = 0;
        }

        return $rankNum;
    }

    // 获取服务器当前时间
    public function getServerTime(){
        $time = time();
        $this->response(0, "ok",$time);
    }

    // 转发记录接口 转发次数人数记录
    public function forward(){
        $uid = isset($this->uid)?$this->uid:I('post.id');  // 用户ID
        $type = I('type','','int'); // 1:查询;2:添加;3:删除
        $type_table = 'sd';   // redis表
        $invite_uid = I('invite_uid','','int');
        $this->getForward($uid,$invite_uid,$type_table,$type);
    }
    
}